package com.bsg.upm.service;

import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.bsg.upm.check.BackupStrategyCheck;
import com.bsg.upm.check.CheckResult;
import com.bsg.upm.constant.DictTypeConstants;
import com.bsg.upm.constant.OperateDictConstants;
import com.bsg.upm.constant.OperateDictTypeConstants;
import com.bsg.upm.dto.BackupStrategyDto;
import com.bsg.upm.entity.BackupStrategyEntity;
import com.bsg.upm.entity.ServEntity;
import com.bsg.upm.entity.UserEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;
import com.bsg.upm.util.DateUtils;
import com.bsg.upm.util.PrimaryKeyUtils;

/**
 * 备份策略管理业务处理类
 * 
 * @author HCK
 *
 */
@Service
public class BackupStrategyService extends BaseService {

	@Resource
	private BackupStrategyCheck backupStrategyCheck;

	/**
	 * 获取备份策略列表
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson list(String servId) throws APIException {
		try {
			JSONArray retJsonArray = new JSONArray();

			// 获取指定服务的备份策略
			List<BackupStrategyEntity> backupStrategys = backupStrategyDao.listByServId(servId);

			for (BackupStrategyEntity backupStrategy : backupStrategys) {
				// 构建备份策略展示对象
				BackupStrategyDto backupStrategyDto = buildShowDto(backupStrategy, false);
				retJsonArray.add(backupStrategyDto);
			}

			return RespJsonFactory.buildOK(retJsonArray);
		} catch (Exception e) {
			logger.error("备份策略查询异常", e);
			throw new APIException("备份策略查询异常:" + e.getMessage());
		}
	}

	/**
	 * 获取备份策略
	 * 
	 * @param backupStrategyId
	 *            备份策略编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson get(String backupStrategyId) throws APIException {
		try {
			// 获取指定的备份策略
			BackupStrategyEntity backupStrategy = backupStrategyDao.get(backupStrategyId);

			if (backupStrategy == null) {
				return RespJsonFactory.build(HttpStatus.SC_GONE, "该备份策略不存在");
			}

			// 构建备份策略展示对象
			BackupStrategyDto backupStrategyDto = buildShowDto(backupStrategy, true);

			return RespJsonFactory.buildOK(backupStrategyDto);
		} catch (Exception e) {
			logger.error("备份策略获取异常", e);
			throw new APIException("备份策略获取异常:" + e.getMessage());
		}
	}

	/**
	 * 备份策略新增
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson save(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_ADD;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 新增检查
			CheckResult chkRS = backupStrategyCheck.checkSave(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 构建备份策略对象
			BackupStrategyEntity backupStrategy = buildBackupStrategy(paramMap);
			backupStrategyDao.save(backupStrategy);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_BACKUP_STRATEGY, operateAcion, backupStrategy.getId(),
					backupStrategy.getCronExpression(), backupStrategy.getCreateDateTime());

			return RespJsonFactory.buildCreated();
		} catch (Exception e) {
			logger.error("备份策略" + operateAcionText + "异常", e);
			throw new APIException("备份策略" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 备份策略编辑
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson update(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_UPDATE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 编辑检查
			CheckResult chkRS = backupStrategyCheck.checkUpdate(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 构建备份策略对象
			BackupStrategyEntity backupStrategy = buildBackupStrategyToUpdate(paramMap);
			backupStrategyDao.update(backupStrategy);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_BACKUP_STRATEGY, operateAcion, backupStrategy.getId(),
					backupStrategy.getCronExpression(), backupStrategy.getCreateDateTime());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("备份策略" + operateAcionText + "异常", e);
			throw new APIException("备份策略" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 备份策略启用/停用
	 * 
	 * @param id
	 *            备份策略编码
	 * @param enable
	 *            是否启用
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson enable(String id, boolean enable) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_DISABLE;
		if (enable) {
			operateAcion = OperateDictConstants.ACTION_ENABLE;
		}
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的备份策略
			BackupStrategyEntity backupStrategy = backupStrategyDao.get(id);

			// 启停检查
			CheckResult chkRS = null;
			if (enable) {
				chkRS = backupStrategyCheck.checkEnable(backupStrategy);
			} else {
				chkRS = backupStrategyCheck.checkDisable(backupStrategy);
			}
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 设置启停状态
			backupStrategy.setEnabled(enable);
			backupStrategyDao.updateEnabled(backupStrategy);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_BACKUP_STRATEGY, operateAcion, backupStrategy.getId(),
					backupStrategy.getCronExpression());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("备份策略" + operateAcionText + "异常", e);
			throw new APIException("备份策略" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 备份策略删除
	 * 
	 * @param id
	 *            备份策略编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson remove(String id) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_REMOVE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的备份策略
			BackupStrategyEntity backupStrategy = backupStrategyDao.get(id);

			// 删除检查
			CheckResult chkRS = backupStrategyCheck.checkRemove(backupStrategy);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			backupStrategyDao.remove(id);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_BACKUP_STRATEGY, operateAcion, backupStrategy.getId(),
					backupStrategy.getCronExpression());

			return RespJsonFactory.buildNoContent();
		} catch (Exception e) {
			logger.error("备份策略" + operateAcionText + "异常", e);
			throw new APIException("备份策略" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 构建备份策略展示
	 * 
	 * @param backupStrategy
	 *            备份策略对象
	 * @param showDetail
	 *            是否展示详情
	 * @return 备份策略展示
	 */
	private BackupStrategyDto buildShowDto(BackupStrategyEntity backupStrategy, boolean showDetail) {
		BackupStrategyDto backupStrategyDto = new BackupStrategyDto();
		backupStrategyDto.setId(backupStrategy.getId());
		backupStrategyDto.setType(backupStrategy.getType());
		backupStrategyDto
				.setTypeText(dictTypeCache.getTextFromCache(DictTypeConstants.BACKUP_TYPE, backupStrategy.getType()));
		backupStrategyDto.setCronExpression(backupStrategy.getCronExpression());
		backupStrategyDto.setRetention(backupStrategy.getRetention());
		backupStrategyDto.setExpireDatetime(DateUtils.dateTimeToString(backupStrategy.getExpireDatetime()));
		backupStrategyDto.setEnabled(backupStrategy.getEnabled());
		String enabledText = dictTypeCache.getTextFromCache(DictTypeConstants.STATUS_ENABLED,
				String.valueOf(backupStrategy.getEnabled()));
		backupStrategyDto.setEnabledText(enabledText);
		backupStrategyDto.setCreateDateTime(DateUtils.dateTimeToString(backupStrategy.getCreateDateTime()));
		backupStrategyDto.setCreateLoginUserName(backupStrategy.getCreateUserLoginName());
		return backupStrategyDto;
	}

	/**
	 * 构建备份策略对象
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return 备份策略对象
	 */
	private BackupStrategyEntity buildBackupStrategy(Map<String, Object> paramMap) throws ParseException {
		BackupStrategyEntity backupStrategy = new BackupStrategyEntity();
		backupStrategy.setId(PrimaryKeyUtils.uniqueId());
		backupStrategy.setType(StringUtils.trim((String) paramMap.get("type")));
		backupStrategy.setCronExpression(StringUtils.trim((String) paramMap.get("cronExpression")));
		if (paramMap.containsKey("expireDatetime")) {
			Long expireDatetime = (Long) paramMap.get("expireDatetime");
			backupStrategy.setExpireDatetime(new Date(expireDatetime));
		}
		ServEntity serv = new ServEntity();
		serv.setId((String) paramMap.get("servId"));
		backupStrategy.setServ(serv);

		backupStrategy.setRetention((Integer) paramMap.get("retention"));
		backupStrategy.setRemark(StringUtils.trim((String) paramMap.get("remark")));
		backupStrategy.setEnabled(true);
		backupStrategy.setCreateDateTime(systemDao.getCurrentDateTime());
		UserEntity user = getUser();
		String username = user.getUsername();
		backupStrategy.setCreateUserLoginName(username);
		return backupStrategy;
	}

	private BackupStrategyEntity buildBackupStrategyToUpdate(Map<String, Object> paramMap) throws ParseException {
		BackupStrategyEntity backupStrategy = backupStrategyDao.get((String) paramMap.get("backupStrategyId"));
		if (paramMap.containsKey("type")) {
			backupStrategy.setType(StringUtils.trim((String) paramMap.get("type")));
		}

		if (paramMap.containsKey("cronExpression")) {
			backupStrategy.setCronExpression(StringUtils.trim((String) paramMap.get("cronExpression")));
		}

		if (paramMap.containsKey("expireDatetime")) {
			Long expireDatetime = (Long) paramMap.get("expireDatetime");
			backupStrategy.setExpireDatetime(new Date(expireDatetime));
		}

		if (paramMap.containsKey("retention")) {
			backupStrategy.setRetention((Integer) paramMap.get("retention"));
		}

		if (paramMap.containsKey("remark")) {
			backupStrategy.setRemark(StringUtils.trim((String) paramMap.get("remark")));
		}
		return backupStrategy;
	}
}
